import axios from 'axios'
import { Toast } from 'antd-mobile'
import qs from 'qs'
import store from 'store'
import config from '../config'

let requestTicket = false;
let requestTicketTimeout = null;

axios.interceptors.request.use(config => {
    // Toast.loading('', 0)
    return config
}, err => {
    return Promise.reject(err)
})

axios.interceptors.response.use(res => {
    Toast.hide()
    return res
}, err => {
    if (err && err.response) {
        switch (err.response.status) {
            case 400:
                Toast.fail(err.response.data.message, 1)
                break
            case 401:
                // if (err.response.data.message !== "账号或密码错误") {
                // window.location.href = '/login'
                // }
                Toast.fail(err.response.data.message, 1)
                break
            case 403:
                //Toast.fail(err.response.data.message, 1)
                sessionStorage.removeItem('ticket')
                window.top.location.reload();
                break
            case 404:
                Toast.fail(err.response.data.message, 1)
                break
            case 405:
                Toast.fail(err.response.data.message, 1)
                break
            case 408:
                Toast.fail(err.response.data.message, 1)
                break
            case 422:
                Toast.hide()
                console.warn('422 message')
                // let errMessage = ''
                // err.response.data.errors.message.default.map((data) =>{
                //   for (const key in data) {
                //     data[key].map((mapData)=>{
                //       errMessage += mapData + ','
                //     })
                //   }
                // })
                // console.log(errMessage)
                // Toast.fail(errMessage,1)
                // Toast.hide()
                console.warn((Object.keys(err.response.data.errors.message || {}) || []).map(k => { return err.response.data.errors.message[k].join(',') }).join('\n') || '网络不给力！！请稍后再试')
                // Toast.fail((Object.keys(err.response.data.errors.message||{})||[]).map(k => {return err.errors.message.default[k].join(',')}).join('\n')||'网络不给力！！请稍后再试', 1)
                if (err.response.data.message === '请重新登录') {
                    store.remove('token');
                    store.remove('user');
                    window.location.href = '/login'
                    // window.location.reload(true)
                }
                break
            case 500:
                if (err.response.data.message === 'Unauthenticated.') {
                    store.remove('token');
                    store.remove('user');
                    window.location.href = '/login'
                    // window.location.reload(true)
                } else {
                    Toast.fail('网络不给力！！请稍后再试', 1)
                }
                break
            case 501:
                Toast.fail(err.response.data.message, 1)
                break
            case 502:
                Toast.fail(err.response.data.message, 1)
                break
            case 503:
                Toast.fail(err.response.data.message, 1)
                break
            case 504:
                Toast.fail(err.response.data.message, 1)
                break
            case 505:
                Toast.fail(err.response.data.message, 1)
                break
            default:
                Toast.fail(err.response.data.message, 1)
        }
    } else {
        Toast.fail(`服务器连接失败`, 1)
    }
    return Promise.reject(err)
})

// 请求获取凭证接口
const requestTicketApi = (resolve) => {
    axios.post(config.api.serviceUrl + '/ticket', {}, { timeout: 10000 }).then((res) => {
        res.data.expiration += (new Date().getTime() / 1000);
        sessionStorage.setItem('ticket', JSON.stringify(res.data));
        resolve(res.data.ticket_id)
    })
}

// 获取凭证
const getTicketRequest = () => {
    return new Promise((resolve, reject) => {
        let ticket = sessionStorage.ticket ? JSON.parse(sessionStorage.ticket) : {};
        if (ticket && ticket.expiration > (new Date().getTime() / 1000)) {
            requestTicketTimeout && clearTimeout(requestTicketTimeout);
            requestTicket = false;
            resolve(ticket.ticket_id)
        } else {
            if (requestTicket) {
                clearTimeout(requestTicketTimeout);
                requestTicketTimeout = setTimeout(() => {
                    requestTicket = false;
                }, 5000);
                setTimeout(() => {
                    resolve('next');
                }, 100);
            } else {
                requestTicketApi(resolve)
                requestTicket = true;
            }
        }
    })
}

const requestMethod = (url, opt, params, auth, method, isLoading = true, hasFile = false) => {
    getTicketRequest().then((ticket) => {
        if (ticket === '') {
            Toast.fail('获取凭证失败')
        } else if (ticket === 'next') {
            return requestMethod(url, opt, params, auth, method);
        } else {
            if (auth && !store.get('token')) {
                // window.location.href = '/login'
                console.error('需要登录状态', url)
                return
            }

            let newUrl = url
            if (method === 'get') {
                if (params) {
                    Object.keys(params).forEach((key, index) => {
                        if (index === 0) {
                            newUrl = newUrl + '?' + key + '=' + params[key]
                        } else {
                            newUrl = newUrl + '&' + key + '=' + params[key]
                        }
                    })
                }
            }

            let fileHeaders = {}
            if (hasFile) {
                fileHeaders = { 'content-type': 'application/x-www-form-urlencoded' }
            }
            
            if (isLoading) {
                Toast.loading('', 0) //增加请求中状态  
            }


            return axios({
                method: method,
                url: newUrl,
                data: method !== 'get' ? params : null,
                timeout: 20000,
                headers: auth ? {
                    'X-ticket': ticket,
                    'Authorization': store.get('token').value,
                    ...fileHeaders,
                } : {
                        'X-ticket': ticket,
                        ...fileHeaders,
                    }
            }).then((res) => {
                return opt.success && opt.success(res.data)
            }).catch((err) => {
                console.log('api error', err)
                err = err.response; // 转response
                // console.log('api error', err, 'newUrl', newUrl, 'err.response')
                if (err) {
                    // message总是错误，汇总一下
                    if (err.status === 422) { // 422的统一提示2s后继续执行
                        Toast.fail((Object.keys(err.data.errors.message || {}) || []).map(k => { return err.data.errors.message[k].join(',') }).join('\n') || '网络不给力！！请稍后再试', 3, () => {
                            return opt.error && opt.error(err.data)
                        })

                    } else {
                        return opt.error && opt.error(err.data)
                    }
                }
            })
        }
    })
}

export default {
    post(url, opt, params = {}, auth = true) {
        requestMethod(url, opt, params, auth, 'post')
    },
    postFile(url, file, opt) {
        const formData = new FormData();
        formData.append('file', file, file.name)

        let isFile = true, isLoading = true
        requestMethod(url, opt, formData, true, 'post', isLoading, isFile)

        // return axios.post(url, formData, config).then((res) => {
        //   return opt.success && opt.success(res.data)
        // }).catch((error) => {
        //   return opt.error && opt.error(error)
        // })
    },
    get(url, opt, params = {}, auth = true) {
        requestMethod(url, opt, params, auth, 'get')
    },
    put(url, opt, params = {}, auth = true) {
        requestMethod(url, opt, params, auth, 'put')
    },
    // 后台静默请求, 没有请求中的状态
    bgPost(url, opt, params = {}, auth = true) {
        let isLoading = false
        requestMethod(url, opt, params, auth, 'post', isLoading)
    },
}
